const fs = require("fs");
const Api = require("./Api");

class HarParser {

    /**
     * 构造函数，初始化 HarParser 类的实例。
     * @param {string} harFilePath - HAR 文件的路径。
     * @param {{url: {includes: string}}[]} harFilterConfigs - 过滤 API 的配置。
     */
    constructor(harFilePath, harFilterConfigs = []) {
        /** @type {Object[]} */
        this.harEntries = JSON.parse(fs.readFileSync(harFilePath).toString()).log.entries;
        this.harEntries = this.harEntries
            .filter(entrie => entrie.response.headers.find(header => header.name.toLowerCase() === "content-type" && header.value.includes("application/json")))
            .sort((entrie1, entrie2) => {
                let startTimestamp1 = new Date(entrie1.startTimestamp).getTime();
                let startTimestamp2 = new Date(entrie2.startTimestamp).getTime();
                let endTimestamp1 = new Date(entrie1.endTimestamp).getTime();
                let endTimestamp2 = new Date(entrie2.endTimestamp).getTime();
                if (startTimestamp1 === startTimestamp2) {
                    return endTimestamp1 - endTimestamp2;
                }
                return startTimestamp1 - startTimestamp2;
            });
        this.harEntries = this.harEntries.filter(entrie => {
            for (let harFilterConfig of harFilterConfigs) {
                if (harFilterConfig && entrie.request.url.includes(harFilterConfig.url.includes)) {
                    return false;
                }
            }
            return true;
        });
    }

    /**
     * 解析 HAR 文件并返回解析后的 API 列表。
     * @returns {Api[]} - 解析后的 API 列表。
     */
    parse() {
        let baseTimestamp = this.harEntries[0] && new Date(this.harEntries[0].startedDateTime).getTime();
        let apis = this.harEntries = this.harEntries.map((harEntrie, index) => {
            let url = new URL(harEntrie.request.url);
            let method = harEntrie.request.method.toUpperCase();
            let headers = harEntrie.request.headers;
            let request = null;
            if (harEntrie.request.queryString) {
                request = harEntrie.request.queryString.reduce((acc, query) => { acc[query.name] = query.value; return acc }, {});
            }
            if (harEntrie.request.postData) {
                request = JSON.parse(harEntrie.request.postData.text);
            }
            let response = harEntrie.response.content.text ? JSON.parse(harEntrie.response.content.text) : {};
            let startTime = new Date(harEntrie.startedDateTime).getTime() - baseTimestamp;
            let endTime = startTime + Math.floor(harEntrie.time);
            const api = new Api(String(index + 1).padStart(3, "0"), url, method, headers, request, response, startTime, endTime);
            return api;
        });
        return apis;
    }
}

module.exports = HarParser;


